package com.allwees.bs.module.pms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.allwees.bs.core.modelbase.branch.BranchUser;
import com.allwees.bs.core.modelbase.branch.EBranchType;
import com.allwees.bs.module.pms.dto.ProductDto;
import com.allwees.bs.module.pms.entity.Category;
import com.allwees.bs.module.pms.entity.Product;
import com.allwees.bs.module.pms.req.query.ProductAuditLogQueryReq;
import com.allwees.bs.module.pms.req.query.ProductQueryReq;
import com.allwees.bs.module.pms.service.BaseProductService;
import com.allwees.bs.module.pms.service.GeneralProductService;
import com.allwees.bs.module.pms.util.ProductCodeUtil;
import com.allwees.bs.module.pms.vo.OnSaleStatVo;
import com.allwees.bs.module.pms.vo.ProductAuditLogVo;
import com.allwees.bs.module.pms.vo.PublishStatVo;
import com.allwees.bs.module.pms.vo.PutoffStatVo;
import com.allwees.core.common.constant.EStatus;
import com.allwees.core.dao.util.PageUtil;
import me.zhengjie.utils.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 *
 *
 * @author yangylsky
 * @since 2019-08-21
 *
 */
@Service
public class GeneralProductServiceImpl extends BaseProductServiceImpl implements GeneralProductService {

	@Resource
	private BaseProductService baseProductService;

	@Override
	public IPage<ProductDto> page(Page<Product> page, ProductQueryReq req) {
		//让retailer和supplier只能看到自己的商品
		BranchUser branchUser = req.getBranchUser();
		EBranchType branchType = branchUser.getBranchType();
		if (branchType == EBranchType.RETAILER){
			req.setRetailerUuid(branchUser.getRetailerUuid());
		} else if (branchType == EBranchType.SUPPLIER){
			req.setSupplierUuid(branchUser.getSupplierUuid());
		}

		//类目处理
		String categoryNo = req.getCategoryNo();
		if(StringUtils.isNotBlank(categoryNo)){
			//类目没有等级属性，这里先根据类目的长度做一个判断：长度为2位为一级类目，长度为5位为二级类目
			List<String> categoryNos = Lists.newArrayList(categoryNo);
			if(categoryNo.length() == 2){
				List<Category> list = categoryDao.findListByField("parent_no", categoryNo);
				if(!CollectionUtils.isEmpty(list)){
					categoryNos.addAll(list.stream().map(Category::getNo).collect(Collectors.toList()));
				}
			}
			req.setCates(categoryNos);
		}

		findPage(page, req);
		return PageUtil.convert(page, ProductDto::of);
	}

	@Override
	public List<ProductAuditLogVo> findAuditLog(ProductAuditLogQueryReq req) {
		return baseMapper.findAuditLog(req);
	}

	@Override
	public PublishStatVo queryPublishStat(String branchUuid) {
		int waitAudit = _countProductOnStatus(EStatus.WAIT_AUDIT.value());
		int auditRejected = _countProductOnStatus(EStatus.AUDIT_REJECTED.value());
		return new PublishStatVo(waitAudit, auditRejected);
	}

	@Override
	public OnSaleStatVo queryOnSaleStat(String branchUuid) {
		int onSale = _countProductOnStatus(EStatus.NORMAL.value());
		int sellout = _countProductOnStatus(EStatus.PUTOFF_SELLOUT.value());
		int alarm = baseMapper.countProductAlarm();
		return new OnSaleStatVo(onSale, sellout, alarm);
	}

	@Override
	public PutoffStatVo queryPutoffStat(String branchUuid) {
		int putoffOneself = _countProductOnStatus(EStatus.PUTOFF_ONESELF.value(), EStatus.PUTOFF_EDITING.value());
		int putoffQaFailure = _countProductOnStatus(EStatus.PUTOFF_QA_FAILURE.value());
		int putoffOthers = _countProductOnStatus(EStatus.PUTOFF_OTHERS.value(), EStatus.PUTOFF_SELLOUT.value());
		return new PutoffStatVo(putoffOneself, putoffQaFailure, putoffOthers);
	}

	private int _countProductOnStatus(Integer... status) {
		Assert.notEmpty(status, "status不能为空");
		return baseMapper.selectCount(new QueryWrapper<Product>().in("status", status));
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void addCollections(String productUuid) {
		baseMapper.addCollections(productUuid);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void removeCollections(String productUuid) {
		baseMapper.removeCollections(productUuid);

	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void addShares(String productUuid) {
		baseMapper.addShares(productUuid);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void addSales(String productUuid, int count) {
		baseMapper.addSales(productUuid, count);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void addRefunds(String productUuid, int count) {
		baseMapper.addRefunds(productUuid, count);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void addReviews(String productUuid) {
		baseMapper.addReviews(productUuid);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void addViews(String productUuid) {
		baseMapper.addViews(productUuid);
	}

	@Override
	public void refreshDefNo() {
		QueryWrapper<Product> wrapper = new QueryWrapper<>();
		wrapper.select("id").apply("def_no is null");
		IPage<Product> page;
		for (int pageSize = 1;;) {
			page = super.page(new Page<>(pageSize,1000),wrapper);
			if(CollectionUtils.isEmpty(page.getRecords())){
				return;
			}
			List<Product> collect = page.getRecords().stream().map(p -> {
				Product product = new Product();
				product.setId(p.getId());
				product.setDefNo(ProductCodeUtil.idToCode(product.getId()));
				return product;
			}).collect(Collectors.toList());
			baseProductService.updateBatchById(collect);
			if(page.getRecords().size() < 1000){
				return;
			}
		}
	}
}
